﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Nim.AI
{
    class NimAI
    {
        StateManager statemanager;
        Random gen;

        public NimAI()
        {
            statemanager = new StateManager();
            gen = new Random();
        }

        //Initialization logic
        public void Initialize()
        {
            statemanager.Initialize();
        }

        //Evaluates the moves of all of the players, scores them, and stores them in the statebucket
        public void EvaluateGame(bool winner)
        {
            Dictionary<string, NimState> p1moves = statemanager.Getp1States();
            Dictionary<string, NimState> p2moves = statemanager.Getp2States();

            bool inWinner = false;

            inWinner = winner == true;
            EvaluatePlayer(p1moves,inWinner);
            inWinner = winner == false;
            EvaluatePlayer(p2moves, inWinner);

            statemanager.SaveStates();
        }

        //Evaluates a particular players moves
        public void EvaluatePlayer(Dictionary<string,NimState> player, bool inWinner)
        {
            foreach (KeyValuePair<string, NimState> pair in player)
            {
                List<NimMove> nimMoves = pair.Value.GetMoves();
                foreach (NimMove nimMove in nimMoves)
                {
                    statemanager.AddMoveToStateBucket(pair.Key, nimMove, inWinner);
                }
            }
        }

        //Adds the move to the statemanager
        public void WatchMove(string state, int row, int number, bool player)
        {
            statemanager.AddMove(state, row, number,player);
        }

        //Either: If there is a state in the state bucket for a move, pick the best one, or make a random move
        public NimMove MakeMove(string state)
        {
            NimMove move = null;

            NimState nimState = statemanager.GetState(state);

            if (nimState == null)
            {
                move = GenerateRandomMove();

                
            }
            else
            {
                move = PickBestMove(nimState);
                if (move.Percentage < 0.5) move = GenerateRandomMove();
            }

            return move;
        }

        public NimMove GenerateRandomMove()
        {
            NimMove move = null;

            int row = gen.Next(1, 4);
            int number = gen.Next(1, 7);

            move = new NimMove(row, number);
            return move;
        }

        //For the given state: Loop through all of the moves, rank them according to their win ratio, and return the highest ranking move
        public NimMove PickBestMove(NimState nimState)
        {
            NimMove move = null;

            foreach (NimMove nimMove in nimState.GetMoves())
            {
                if (move == null) move = nimMove;
                else if (nimMove.Percentage > move.Percentage) move = nimMove;
            }
                
            return move;
        }
    }
}
